import 'dart:math';
import 'package:better_cupertino_slider/better_cupertino_slider.dart';
import 'package:flutter/material.dart';
import 'package:painter_demo/gen/assets.gen.dart';
import 'package:painter_demo/widgets/ratio_util.dart';
import 'package:painter_demo/widgets/slider_controller.dart';

typedef ValueChanged = void Function(double value);

class SliderHorizontal extends StatefulWidget {
  /// size 是画布大小 实际宽度还需要要比这个大 imgWidth
  final double size;
  //取值范围 0-100
  final double value;
  //可取最小值
  final double minValue;
  //可取最大值
  final double maxValue;
  final ValueChanged? onChanged;
  final SliderController? sliderController;

  const SliderHorizontal(
      {super.key,
      required this.size,
      required this.value,
      required this.minValue,
      required this.maxValue,
      this.onChanged,
      this.sliderController})
      : assert(maxValue > minValue),
        assert(value >= minValue),
        assert(value <= maxValue);

  @override
  State<SliderHorizontal> createState() => _SliderHorizontalState();
}

class _SliderHorizontalState extends State<SliderHorizontal> {
  double get imgWidth {
    return 77.gr;
  }

  double get imgLeft {
    return 15.gr;
  }

  //当前所在值 取值范围0-100
  double currentValue = 0;
  double get imgDx {
    var rate =
        (currentValue - widget.minValue) / (widget.maxValue - widget.minValue);
    return widget.size * 0.2 - 20.gr + rate * (widget.size * 0.6);
    // * currentValue / 100 - 20.gr;
  }

  @override
  void initState() {
    super.initState();
    RatioUtil.init(size: widget.size, designSize: 300);
    currentValue = widget.value;
    widget.sliderController?.addStep = addStep;
    widget.sliderController?.subStep = subStep;
  }

  void addStep() {
    onChanged(currentValue + 0.1);
  }

  void subStep() {
    onChanged(currentValue - 0.1);
  }

  void onChanged(double value) {
    if (value < widget.minValue) {
      value = widget.minValue;
    }
    if (value > widget.maxValue) {
      value = widget.maxValue;
    }
    widget.onChanged?.call(value);
    setState(() {
      currentValue = value;
    });
  }

  @override
  Widget build(BuildContext context) {
    var size = widget.size;
    return SizedBox(
      width: size + imgWidth,
      height: size + imgWidth,
      child: Stack(
        clipBehavior: Clip.none,
        children: [
          Padding(
            padding: EdgeInsets.only(left: imgWidth, top: imgWidth),
            child: CustomPaint(
              size: Size(size, size),
              painter: VerticalPainter(
                  minValue: widget.minValue,
                  maxValue: widget.maxValue,
                  value: currentValue),
            ),
          ),
          Positioned(left: 0, bottom: imgDx, child: _buildImg()),
          Positioned(
            height: 0.6 * size,
            bottom: 0.2 * size,
            left: 0,
            right: 0,
            child: RotatedBox(
              quarterTurns: 3,
              child: _buildSlider(),
            ),
          ),
        ],
      ),
    );
  }

  Widget _buildSlider() {
    return BetterCupertinoSlider(
      min: widget.minValue,
      max: widget.maxValue,
      value: currentValue,
      configure: BetterCupertinoSliderConfigure(
        trackHorizontalPadding: 0.gr,
        trackHeight: 20.gr,
        trackLeftColor: Colors.transparent,
        trackRightColor: Colors.transparent,
        thumbRadius: 20.gr,
        thumbPainter: (canvas, rect) {
          final RRect rrect = RRect.fromRectAndRadius(
            rect,
            Radius.circular(rect.shortestSide / 2.0),
          );
          canvas.drawRRect(rrect, Paint()..color = Colors.transparent);
        },
      ),
      onChanged: onChanged,
    );
  }

  Widget _buildImg() {
    return Stack(
      children: [
        Image.asset(
          Assets.images.horizontalHandle.path,
          width: imgWidth,
        ),
        Positioned.fill(
          left: imgLeft,
          right: 0,
          bottom: 0,
          top: 0,
          child: Container(
            alignment: Alignment.center,
            child: Text(currentValue.toStringAsFixed(1),
                style: TextStyle(color: Colors.white, fontSize: 16.gr)),
          ),
        )
      ],
    );
  }
}

class VerticalPainter extends CustomPainter {
  final double maxValue;
  final double minValue;
  final double value;

  VerticalPainter(
      {required this.maxValue, required this.minValue, required this.value});

  TextPainter getTextPainter(String text) {
    return TextPainter(
      text: TextSpan(text: text, style: TextStyle(fontSize: 16.gr)),
      textDirection: TextDirection.rtl,
    )..layout(minWidth: 0, maxWidth: 20);
  }

  @override
  void paint(Canvas canvas, Size size) {
    final double axisLength = size.width;
    final Offset origin = Offset(0, size.height);
    final Paint axisPaint = Paint()
      ..color = Colors.white
      ..strokeWidth = 5.0.gr
      ..style = PaintingStyle.stroke
      ..strokeJoin = StrokeJoin.round
      ..strokeCap = StrokeCap.round;

    final hPainter = getTextPainter('H');
    hPainter.paint(canvas, origin + Offset(-5, -axisLength - 30));

    final qPainter = getTextPainter('Q');
    qPainter.paint(canvas, origin + Offset(axisLength + 10, -10));

    final Path xyPath = Path()
      ..moveTo(0, 0)
      ..lineTo(0, origin.dy)
      ..lineTo(origin.dy, origin.dy);
    canvas.drawPath(xyPath, axisPaint);

    // final zeroPainter = getTextPainter('0');
    // zeroPainter.paint(canvas, Offset(-20, origin.dy - 10));

    //0.2 的位置点
    final realLength = 0.6 * axisLength;
    final minPainter = getTextPainter(minValue.toStringAsFixed(0));
    final minDy = origin.dy - 0.2 * axisLength;
    minPainter.paint(canvas, Offset(-25, minDy - 8.gr));

    final maxPainter = getTextPainter(maxValue.toStringAsFixed(0));
    final maxDy = origin.dy - 0.8 * axisLength;
    maxPainter.paint(canvas, Offset(-25, maxDy - 8.gr));

    // 绘制从X轴到Y轴的顶点的弧形
    final double arcRadius = axisLength;
    final Rect arcRect = Rect.fromCircle(center: origin, radius: arcRadius);
    final Paint arcPaint = Paint()
      ..color = const Color(0x99FFFFFF)
      ..style = PaintingStyle.stroke
      ..strokeWidth = 1.0;

    canvas.drawArc(arcRect, -pi / 2, pi / 2, false, arcPaint);

    final Path rectPath = Path()
      ..moveTo(calculateB(axisLength, axisLength - minDy), minDy)
      ..lineTo(0, minDy)
      ..lineTo(0, maxDy)
      ..lineTo(calculateB(axisLength, axisLength - maxDy), maxDy)
      ..arcToPoint(Offset(calculateB(axisLength, axisLength - minDy), minDy),
          radius: Radius.circular(axisLength));
    final Paint rectPaint = Paint()
      ..color = const Color(0x61FFFFFF)
      ..style = PaintingStyle.fill;

    canvas.drawPath(rectPath, rectPaint);

    final Paint strokePaint = Paint()
      ..color = Colors.white
      ..strokeWidth = 1
      ..style = PaintingStyle.stroke;

    canvas.drawPath(rectPath, strokePaint);

    //百分比
    final rate = (value - minValue) / (maxValue - minValue);
    final double posY = axisLength - (0.2 * axisLength + rate * realLength);
    final startPoint = Offset(calculateB(axisLength, axisLength - posY), posY);
    final endPoint = Offset(0, posY);

    final Paint soildPaint = Paint()
      ..color = Colors.white
      ..strokeWidth = 4.0.gr;

    final Paint soildPaint1 = Paint()
      ..color = const Color(0x61FFFFFF)
      ..strokeWidth = 12.0.gr;

    // 杆子
    canvas.drawLine(startPoint, endPoint, soildPaint1);
    canvas.drawLine(startPoint, endPoint, soildPaint);

    //圆头
    canvas.drawOval(
        Rect.fromCircle(center: startPoint, radius: 8.gr), soildPaint);
    canvas.drawOval(
        Rect.fromCircle(center: startPoint, radius: 12.gr), soildPaint1);
  }

  double calculateB(double c, double a) {
    return sqrt(c * c - a * a);
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) {
    return true;
  }
}
